#include "v_tracking.h"
#include "sim900.h"
#include "var.h"
#include <string.h>
#include "serial.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
RxBuffer rxBuf;
unsigned char sim_smsArrived = 0;
unsigned char sim_smsArriveFlag = 0;
unsigned char sim_callDoneFlag = 0;
static unsigned char sim_cmdFlag = 0;
char sim_callBuf[MAX_RX_BUF];
  SimCmd sim_cmd;  //kiem tra xem trong C, khai bao con tro tro toi 1 struct thi mat bao nhieu bo nho
void UART5_IRQHandler(void)
{
  static portBASE_TYPE xTaskWoken = pdFALSE; 
  unsigned char i = 0;
  char *start_pos;
  char *stop_pos;
  char newsms[20];
  char temp = 0;
  temp = (char)UART5->DR;
  rxBuf.sim_rxBuf[rxBuf.sim_rxBufPointer++] = temp;
  if(rxBuf.sim_rxBufPointer >= MAX_RX_BUF)
    rxBuf.sim_rxBufPointer = 0;
  //xu ly tim kiem tin nhan
  start_pos = strstr(rxBuf.sim_rxBuf,"\r\n+CMTI:"); //chuoi can tim kiem cang day du thi cang do phai tim kiem them nhieu buoc tiep theo
  if(start_pos)
  {
    stop_pos = strchr(start_pos + 2,'\n');
    if(stop_pos)
    {
      memcpy(newsms,start_pos,stop_pos-start_pos+1);
      xQueueSendFromISR(Sim_NewSMSQueue,newsms,&xTaskWoken); 
      return;       
    }
    return;
    //give semaphoen toi task xu ly co tin nhan den

//      if(xTaskWoken == pdTRUE)
//      {
//        vTaskSwitchContext();
//        //force context switch
//      }
   
  }
//    if(strncmp(sim_rxBuf,"\r\n+CLIP",7))
//    {
//      if(sim_callDoneFlag)    //co gang thay the Flag bang semaphone hoac cai gi do :D
//      {
//        for(i = 0; i < sim_rxBufLen; i++) //
//          sim_callBuf[i] = sim_rxBuf[i];
//        sim_callDoneFlag = 0;   //sim_callDoneFlag se duoc set lai ngay khi chan RI bi keo xuong(co su kien cuoc goi/tin nhan)
//        //give semaphore toi task xu ly cuoc goi
//        xSemaphoreGiveFromISR(xSem_sim_incommingCall,&xTaskWoken);
////       if(xTaskWoken == pdTRUE)
////        {
////          vTaskSwitchContext();
////        //force context switch
////        }       
//        return;
//      }
//    }
}
void SIM_SendCmd(SimCmd *cmd)
{
  char *pos;
  //reset con tro, con du lieu co san thuc ra van khong mat. SU dung cach nay do cau lenh la chu dong gui. Xem xet co can reset con tro sau khi xac nhan la co t/n hoac co cuoc goi k
  rxBuf.sim_rxBufPointer = 0;

  USART_SendString(GSM_USART,cmd->cmd);
  vTaskDelay(cmd->timeOut);       //trong thoi gian cho timeout co the di lam viec khac :D, co ve khong lang phi thoi gian 
  pos = strstr(rxBuf.sim_rxBuf,cmd->cmd);
  if(pos)
  {
    if(strstr(pos + 1,"\r\nOK"))
    {
      cmd->status = CMD_OK;
    }
    else
      cmd->status = CMD_ERR;
  }
  xSemaphoreGive(xSem_sim_cmd);
}
uint8_t GSM_AddTask(SimCmd *sim_cmd,char *cmd, uint8_t type, uint32_t timeOut, uint8_t retry)
{

  
  memcpy(sim_cmd->cmd,cmd,strlen(cmd)+1);
  sim_cmd->cmdType = type;
  sim_cmd->timeOut = timeOut;
  sim_cmd->retry = retry;
  sim_cmd->status = CMD_ERR;
  if(xQueueSend(Sim_CmdQueue,sim_cmd,portMAX_DELAY) == pdTRUE)
  {
    USART_SendString(PC_USART,"Current Task: Add Command successfuly\r\n");
  }
  else
    USART_SendString(PC_USART,"Current Task: Add Command Fail\r\n"); 
  if(xSemaphoreTake(xSem_sim_cmd,sim_cmd->timeOut) == pdTRUE)
  {
    return sim_cmd->status;
  }
}
void vGSMTask(void *arg)
{
  SimCmd *sim_cmd;
  sim_cmd = (SimCmd *)arg;
  for(;;)
  {
    
    if(xQueueReceive(Sim_CmdQueue,sim_cmd,portMAX_DELAY) == pdTRUE)
    {
      
      switch(sim_cmd->cmdType)
      {
        case SendCmd:
              //USART_SendString(PC_USART,"GSM Task: Bat dau Gui Lenh\r\n");
              SIM_SendCmd(sim_cmd);
          break;
        case ConnectToServer:
          break;
        case WriteDataNoResp:
          break;
        case SendSMS:
          break;
        case ReadSMS:
          break;
        case Call:
          break;        
      }
    }
  }
}
void vProcessNewSMS(void *arg)
{
  char sim_newSMSBuf[20];
  for(;;)
  {
      xQueueReceive(Sim_NewSMSQueue,sim_newSMSBuf,portMAX_DELAY);
        USART_SendString(PC_USART,"Task3: Co tin nhan moi\r\n");
  }
}
void vProcessIncommingCall(void *arg)
{
  for(;;)
  {
      if(xSemaphoreTake(xSem_sim_incommingCall,portMAX_DELAY) == pdTRUE)
        USART_SendString(PC_USART,"Task4: Co cuoc goi moi\r\n");
  }
}